package com.moss.cloud.common.security.annotation.aspect;

import com.moss.cloud.common.core.exception.SystemErrorType;
import com.moss.cloud.common.core.utils.BooleanHandel;
import com.moss.cloud.common.core.utils.UserContextHolder;
import com.moss.cloud.common.security.annotation.RequiresRole;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色权限校验实现--某些接口或者方法必须是指定的角色或者必须有角色的用户才能操作
 *
 * @author 瑾年
 * @data 2020/05/05
 */
@Slf4j
@Aspect
@Component
public class RequiresRoleImpl {
    /**
     * 环绕通知
     *
     * @author 瑾年
     * @data 2023年11月12日
     */
    @Around("@annotation(requiresRole)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint, RequiresRole requiresRole) throws Throwable {
        List<Long> roleIds = UserContextHolder.getRoleIds();
        List<String> roleCodes = UserContextHolder.getRoleCodes();
        BooleanHandel.isTrue(requiresRole != null).trueHandle(() -> {
            log.info("用户是否无角色:{}", CollectionUtils.isEmpty(roleIds));
            // 无角色用户无权查看数据
            BooleanHandel.trueThrow(CollectionUtils.isEmpty(roleIds)).throwMessage(SystemErrorType.NO_ROLE);
        });
        BooleanHandel.isTrue(CollectionUtils.isNotEmpty(Arrays.stream(requiresRole.codes()).collect(Collectors.toList())))
                .trueHandle(() -> {
                    log.info("允许操作的角色: {},用户角色:{}", requiresRole.codes(),roleCodes.toString());
                    BooleanHandel
                            .trueThrow(roleCodes.stream().noneMatch(Arrays.asList(requiresRole.codes())::contains))
                            .throwMessage(SystemErrorType.CODE_NO_ROLE);
                });
        return proceedingJoinPoint.proceed();
    }

}
